﻿using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Infrastructure;
using Nop.Services.Logging;
using Nop.Web.Framework;
using Nop.Web.Framework.Security;
using Nop.Web.Framework.UI;

namespace Nop.Web.Controllers
{
    [StoreLastVisitedPage]
    [CheckAffiliate]
    [StoreClosedAttribute]
    [PublicStoreAllowNavigation]
    [LanguageSeoCodeAttribute]
    [NopHttpsRequirement(SslRequirement.NoMatter)]
    public abstract partial class BaseNopController : Controller
    {
        /// <summary>
        /// Log exception
        /// </summary>
        /// <param name="exc">Exception</param>
        private void LogException(Exception exc)
        {
            var workContext = EngineContext.Current.Resolve<IWorkContext>();
            var logger = EngineContext.Current.Resolve<ILogger>();

            var customer = workContext.CurrentCustomer;
            logger.Error(exc.Message, exc, customer);
        }
        /// <summary>
        /// Display success notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void SuccessNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Success, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display notice notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void WarningNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Warning, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display info notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void InfoNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Info, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display error notification
        /// </summary>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void ErrorNotification(string message, bool persistForTheNextRequest = true)
        {
            AddNotification(NotifyType.Error, message, persistForTheNextRequest);
        }
        /// <summary>
        /// Display error notification
        /// </summary>
        /// <param name="exception">Exception</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        /// <param name="logException">A value indicating whether exception should be logged</param>
        protected virtual void ErrorNotification(Exception exception, bool persistForTheNextRequest = true, bool logException = true)
        {
            if (logException)
                LogException(exception);
            AddNotification(NotifyType.Error, exception.Message, persistForTheNextRequest);
        }

        /// <summary>
        /// Display error notification from invalid ModelState
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void ModelStateErrorNotification(bool persistForTheNextRequest = true)
        {
            if (!ModelState.IsValid)
            {
                foreach (var err in ModelState.Values)
                {
                    foreach (var error in err.Errors)
                        AddNotification(NotifyType.Error, error.ErrorMessage, persistForTheNextRequest);
                }
            }
        }

        /// <summary>
        /// Display notification
        /// </summary>
        /// <param name="type">Notification type</param>
        /// <param name="message">Message</param>
        /// <param name="persistForTheNextRequest">A value indicating whether a message should be persisted for the next request</param>
        protected virtual void AddNotification(NotifyType type, string message, bool persistForTheNextRequest)
        {
            string dataKey = string.Format("nop.notifications.{0}", type);
            if (persistForTheNextRequest)
            {
                if (TempData[dataKey] == null)
                    TempData[dataKey] = new List<string>();
                ((List<string>)TempData[dataKey]).Add(message);
            }
            else
            {
                if (ViewData[dataKey] == null)
                    ViewData[dataKey] = new List<string>();
                ((List<string>)ViewData[dataKey]).Add(message);
            }
        }

        /// <summary>
        /// Render notification for ajax responses
        /// </summary>
        protected virtual string RenderAjaxNotification()
        {
            var nte = string.Format("nop.notifications.{0}", NotifyType.Error);
            var nts = string.Format("nop.notifications.{0}", NotifyType.Success);
            var nti = string.Format("nop.notifications.{0}", NotifyType.Info);
            var ntw = string.Format("nop.notifications.{0}", NotifyType.Warning);
            var messages = "";
            if (TempData[nts] != null)
            {
                messages += "<div class='alert alert-success alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><ul>"+RenderList((List<string>)TempData[nts])+"</ul></div>";
                TempData[nts] = null;
            }
            if (TempData[nte] != null)
            {
                messages += "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><ul>" + RenderList((List<string>)TempData[nte]) + "</ul></div>";
                TempData[nte] = null;
            }
            if (TempData[nti] != null)
            {
                messages += "<div class='alert alert-info alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><ul>" + RenderList((List<string>)TempData[nti]) + "</ul></div>";
                TempData[nti] = null;
            }
            if (TempData[ntw] != null)
            {
                messages += "<div class='alert alert-warning alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button><ul>" + RenderList((List<string>)TempData[ntw]) + "</ul></div>";
                TempData[ntw] = null;
            }
            return messages;
        }
        [NonAction]
        protected string RenderList(List<string> list)
        {
            var msg = "";
            if (list.Count > 0)
            { 
                foreach (var s in list)
                {
                    msg += "<li>" + s + "</li>";
                }
            }
            return msg;
        }
    }
}
